package io.xxx.omni.sync.impl

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import io.xxx.omni.sync.Document
import io.xxx.omni.sync.PagePorter
import io.xxx.omni.sync.Store
import io.xxx.omni.util.dateTimeFormatter
import io.xxx.omni.util.toLocalDateTime
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
import org.springframework.web.util.UriComponentsBuilder
import java.time.LocalDateTime

/**
 * 孩子王
 */
abstract class HzwPorter : PagePorter() {

    val httpUrl = "http://dapopen.haiziwang.com/pop/"

    override val platformCode = "haiziwang"

    protected abstract val path: String

    protected fun getResponse(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        timeParamType: Int = 2,
        pageNo: Long = 1,
    ): JSONObject {
        val url = UriComponentsBuilder.fromHttpUrl(httpUrl)
            .path(path)
            .queryParam("appkey", store.appKey)
            .queryParam("loginName", store.accessToken)
            .queryParam("jsonStr", JSON.toJSONString(getParams(startTime, endTime, timeParamType, pageNo)))
            .toUriString()
        val response = restTemplate.getForEntity(url, JSONObject::class.java)
        if (response.statusCode.isError || response.body == null) {
            val msg = "接口[url: $url]异常"
            throw RuntimeException(msg)
        }
        val body = response.body!!
        if (body.getString("errorCode") != "0") {
            val msg = "接口[url: $url]异常: $body"
            log.error(msg)
            throwException(path, null, body.getString("message"))
        }
        return response.body!!
    }

    private fun getParams(
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        timeParamType: Int, // 1. 创建时间，2. 更新时间
        pageNo: Long = 1,
    ): Map<String, String> {
        return mapOf(
            "startTime" to startTime.format(dateTimeFormatter),
            "endTime" to endTime.format(dateTimeFormatter),
            "page" to pageNo.toString(),
            "pageSize" to pageSize.toString(),
            "timeParamType" to timeParamType.toString()
        )
    }

    companion object {
        private val log = LoggerFactory.getLogger(HzwPorter::class.java)
    }
}

@Component
class HzwTradePorter : HzwPorter() {

    override val path = "order.list"

    override val jobId = 1

    override fun getParameters(store: Store): List<Any> {
        return listOf(2)
    }

    override fun getCount(store: Store, startTime: LocalDateTime, endTime: LocalDateTime, parameter: Any?): Long? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getLong("totalNum")
    }

    override fun getData(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?,
        pageNo: Long,
    ): List<Document>? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getJSONArray("data").map {
            @Suppress("unchecked_cast")
            val value = JSONObject(it as Map<String, Any>)
            Document(
                value.getString("dealCode"),
                value,
                value.getLong("LastUpdateTime").toLocalDateTime()
            )
        }
    }
}

@Component
class HzwTradeProcurator : HzwTradePorter() {

    override val jobId = 3

    override val cron = "0/10 * * * * ?"

    override fun getParameters(store: Store): List<Any> {
        return listOf(1)
    }
}

@Component
class HzwRefundPorter : HzwPorter() {

    override val path = "refund.orderList"

    override val jobId = 1

    override fun getParameters(store: Store): List<Any> {
        return listOf(2)
    }

    override fun getCount(store: Store, startTime: LocalDateTime, endTime: LocalDateTime, parameter: Any?): Long? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getLong("totalNum")
    }

    override fun getData(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?,
        pageNo: Long,
    ): List<Document>? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getJSONArray("data").map {
            @Suppress("unchecked_cast")
            val value = JSONObject(it as Map<String, Any>)
            Document(
                value.getString("dealCode"),
                value.getString("dealCode"),
                value,
                value.getString("update_time").toLocalDateTime()
            )
        }
    }
}

@Component
class HzwRefundProcurator : HzwRefundPorter() {

    override val jobId = 4

    override val cron = "0/10 * * * * ?"

    override fun getParameters(store: Store): List<Any> {
        return listOf(1)
    }
}